package com.anji.sp.push.service.impl;

import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.CIDResult;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.IosAlert;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import cn.jpush.api.report.ReceivedsResult;
import com.anji.sp.model.ResponseModel;
import com.anji.sp.push.model.MessageModel;
import com.anji.sp.push.model.po.PushConfiguresPO;
import com.anji.sp.push.model.vo.RequestSendBean;
import com.anji.sp.push.service.PushHistoryService;
import com.anji.sp.push.service.PushService;
import com.anji.sp.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;


/**
 * <p>
 * 极光推送服务类
 * </p>
 *
 * @author kean
 * @since 2021-01-20
 */
@Service
@Slf4j
public class JPushServiceImpl implements PushService {
    @Autowired
    private PushHistoryService pushHistoryService;

    @Override
    public ResponseModel pushBatchMessage(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO, String msgId, String targetType) throws Exception {
        return null;
    }

    @Override
    public ResponseModel pushAllMessage(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO, String msgId, String targetType) throws Exception {
        return null;
    }

    /**
     * android极光推送
     *
     * @param requestSendBean
     * @param pushConfiguresPO
     * @param msgId
     * @param targetType
     * @return
     * @throws Exception
     */
    public ResponseModel pushAndroid(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO, String msgId, String targetType, boolean isFromManu) throws Exception {
        if (StringUtils.isEmpty(pushConfiguresPO.getAppKey()) || StringUtils.isEmpty(pushConfiguresPO.getJgAppKey())
                || StringUtils.isEmpty(pushConfiguresPO.getJgMasterSecret())) {
            return ResponseModel.errorMsg("参数配置不全");
        }
        MessageModel messageModel;
        try {
            messageModel = sendAndroidWithRegisterId(requestSendBean, pushConfiguresPO, isFromManu);
        } catch (Exception e) {
            //有异常再尝试发一次
            messageModel = sendAndroidWithRegisterId(requestSendBean, pushConfiguresPO, isFromManu);
        }
        //保存历史数据
        return pushHistoryService.savePushHistory(requestSendBean, messageModel, msgId, targetType);

    }

    /**
     * ios极光推送
     *
     * @param requestSendBean
     * @param pushConfiguresPO
     * @param msgId
     * @param targetType
     * @return
     * @throws Exception
     */
    public ResponseModel pushIos(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO, String msgId, String targetType) throws Exception {
        if (StringUtils.isEmpty(pushConfiguresPO.getAppKey()) || StringUtils.isEmpty(pushConfiguresPO.getJgAppKey())
                || StringUtils.isEmpty(pushConfiguresPO.getJgMasterSecret())) {
            return ResponseModel.errorMsg("参数配置不全");
        }
        MessageModel messageModel;
        try {
            messageModel = pushIosWithRegisterId(requestSendBean, pushConfiguresPO);
        } catch (Exception e) {
            //有异常再尝试发一次
            messageModel = pushIosWithRegisterId(requestSendBean, pushConfiguresPO);
        }
        //保存历史数据
        return pushHistoryService.savePushHistory(requestSendBean, messageModel, msgId, targetType);

    }


    private MessageModel pushIosWithRegisterId(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO) {
        JPushClient jpushClient = new JPushClient(pushConfiguresPO.getJgMasterSecret(), pushConfiguresPO.getJgAppKey());
        IosAlert alert = IosAlert.newBuilder()
                .setTitleAndBody(requestSendBean.getTitle(), requestSendBean.getTitle(), requestSendBean.getContent())
                .setActionLocKey("PLAY")
                .build();
        try {

            PushPayload payload;
            if ("1".equals(requestSendBean.getPushType())) {//透传消息
                payload = PushPayload.newBuilder()
                        .setPlatform(Platform.ios())
                        .setAudience(Audience.registrationId(requestSendBean.getRegistrationIds()))
                        .setMessage(Message.newBuilder().setTitle(requestSendBean.getTitle()).setMsgContent(requestSendBean.getContent())
                                .addExtras(requestSendBean.getExtras() == null ? (new HashMap<String, String>()) : requestSendBean.getExtras())
                                .build()).build();
            } else {
                payload = PushPayload.newBuilder()
                        .setPlatform(Platform.ios())
                        .setAudience(Audience.registrationId(requestSendBean.getRegistrationIds()))
                        .setNotification(Notification.newBuilder()
                                .addPlatformNotification(IosNotification.newBuilder()
                                        .setAlert(alert)
                                        .setSound(Objects.isNull(requestSendBean.getIosConfig()) ? "default" : requestSendBean.getIosConfig().get("sound"))
                                        .addExtras(requestSendBean.getExtras() == null ? (new HashMap<String, String>()) : requestSendBean.getExtras())
                                        .build())
                                .build()).build();
            }

            PushResult result = jpushClient.sendPush(payload);
            log.info("pushIosWithRegisterId result {}", result);

            if (result.statusCode == 0) {
                //成功
                return MessageModel.success(requestSendBean.getRegistrationIds().size(), requestSendBean.getRegistrationIds().size(),result.getOriginalContent()+"\n");
            } else {
                return MessageModel.errorMsg(requestSendBean.getRegistrationIds().size(), 0, result.getOriginalContent()+"\n");
            }
        } catch (APIConnectionException e) {
            log.error("pushIosWithRegisterId APIConnectionException .", e);
            return MessageModel.errorMsg(requestSendBean.getRegistrationIds().size(), 0, e.getMessage()+"\n");
        } catch (Exception e) {
            log.error("pushIosWithRegisterId Exception .", e);
            return MessageModel.errorMsg(requestSendBean.getRegistrationIds().size(), 0, e.getMessage()+"\n");
        }
    }

    /**
     * @param requestSendBean
     * @param pushConfiguresPO
     * @param isFromManu       是否从厂商过来 从厂商过来需要发个透传
     * @return
     */
    private MessageModel sendAndroidWithRegisterId(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO, boolean isFromManu) {
        JPushClient jPushClient = new JPushClient(pushConfiguresPO.getJgMasterSecret(), pushConfiguresPO.getJgAppKey());
        try {
            CIDResult result = jPushClient.getCidList(3, "push");
            log.info("sendAndroidWithRegisterId result {}.", result);
            return sendPushWithCid(requestSendBean, result.cidlist.get(0), pushConfiguresPO, isFromManu);
        } catch (APIConnectionException e) {
            log.error("sendAndroidWithRegisterId APIConnectionException . ", e);
            return MessageModel.errorMsg(requestSendBean.getRegistrationIds().size(), 0, e.getMessage()+"\n");
        } catch (Exception e) {
            log.error("sendAndroidWithRegisterId Exception . ", e);
            return MessageModel.errorMsg(requestSendBean.getRegistrationIds().size(), 0, e.getMessage()+"\n");
        }
    }

    /**
     * 通过cid发送Android推送
     *
     * @param requestSendBean
     * @param cid
     * @param pushConfiguresPO
     * @return
     */
    private MessageModel sendPushWithCid(RequestSendBean requestSendBean, String cid, PushConfiguresPO
            pushConfiguresPO, boolean isFromManu) {
        JPushClient jPushClient = new JPushClient(pushConfiguresPO.getJgMasterSecret(), pushConfiguresPO.getJgAppKey());
        PushPayload pushPayload = buildPushObject_android_cid(requestSendBean, cid, isFromManu);
        try {
            PushResult result = jPushClient.sendPush(pushPayload);
            log.error("sendPushWithCid result {}", result);
            if (result.statusCode == 0) {
                //推送成功
                return MessageModel.success(requestSendBean.getRegistrationIds().size(), requestSendBean.getRegistrationIds().size(),"请求成功"+"\n");
            } else {
                return MessageModel.errorMsg(requestSendBean.getRegistrationIds().size(), 0, result.getOriginalContent()+"\n");
            }

        } catch (APIConnectionException e) {
            log.error("sendPushWithCid APIConnectionException . ", e);
            return MessageModel.errorMsg(requestSendBean.getRegistrationIds().size(), 0,e.getMessage()+"\n");
        } catch (Exception e) {
            log.error("sendPushWithCid Exception . ", e);
            return MessageModel.errorMsg(requestSendBean.getRegistrationIds().size(), 0, e.getMessage()+"\n");
        }
    }

    /**
     * 创建androidPushPayload
     *
     * @param requestSendBean
     * @param cid
     * @return
     */
    private PushPayload buildPushObject_android_cid(RequestSendBean requestSendBean, String cid, boolean isFromManu) {
        if ("1".equals(requestSendBean.getPushType()) || isFromManu) {//透传消息
            return PushPayload.newBuilder()
                    .setPlatform(Platform.android())
                    .setAudience(Audience.registrationId(requestSendBean.getRegistrationIds()))
                    .setCid(cid)
                    .setMessage(Message.newBuilder().setTitle(requestSendBean.getTitle()).setMsgContent(requestSendBean.getContent())
                            .addExtras(requestSendBean.getExtras() == null ? (new HashMap<String, String>()) : requestSendBean.getExtras())
                            .build())
                    .build();
        } else {//普通消息
            return PushPayload.newBuilder()
                    .setPlatform(Platform.android())
                    .setAudience(Audience.registrationId(requestSendBean.getRegistrationIds()))
                    .setNotification(Notification.android(requestSendBean.getContent(), requestSendBean.getTitle(), requestSendBean.getExtras()))
                    .setCid(cid)
                    .build();
        }
    }

    //如果发厂商推送要发个透传的极光消息来显示声音

    /**
     * @param requestSendBean
     * @param pushConfiguresPO
     * @return
     */
    public ResponseModel setPassThrougnMsg(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO) {
        if (StringUtils.isEmpty(pushConfiguresPO.getAppKey()) || StringUtils.isEmpty(pushConfiguresPO.getJgAppKey())
                || StringUtils.isEmpty(pushConfiguresPO.getJgMasterSecret())) {
            return ResponseModel.errorMsg("参数配置不全");
        }
        if (StringUtils.isNotEmpty(requestSendBean.getAndroidConfig()) && !StringUtils.isBlank(requestSendBean.getAndroidConfig().get("sound").toString())) {
            MessageModel messageModel = sendAndroidWithRegisterId(requestSendBean, pushConfiguresPO, true);
        }
        return ResponseModel.success();
    }

    public ResponseModel getReceiveIdsDetail(String jgMsgIds, String jgMasterSecret,String jgAppKey) {
        JPushClient jPushClient = new JPushClient(jgMasterSecret, jgAppKey);
        ReceivedsResult receivedsDetail = null;
        try {
            receivedsDetail = jPushClient.getReceivedsDetail(jgMsgIds);
        } catch (APIConnectionException e) {
            e.printStackTrace();
        } catch (APIRequestException e) {
            e.printStackTrace();
        }

        return ResponseModel.successData(receivedsDetail);
    }



}
